package com.calligraphy.user.service.impl;

import com.calligraphy.bases.utils.JwtUtil;
import com.calligraphy.user.enums.ResultEnum;
import com.calligraphy.user.exception.UserException;
import com.calligraphy.user.model.User;
import com.calligraphy.user.repository.UserRepository;
import com.calligraphy.user.service.UserService;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import java.time.Instant;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author hy
 * @Date 2018/12/13 17:05
 **/
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    private static final String TOKEN_COOKIE = "token";

    @Value("${file.path}")
    public String fileUploadPath;

    @Autowired
    private UserRepository repository;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public void registerUser(User user) {
        repository.save(user);
    }

    @Override
    public User updateUser(User alter) {
        User User1 = new User();
        BeanUtils.copyProperties(alter,User1);
        User result = repository.save(User1);
        return result;
    }

    @Override
    public User findByEmail(String email) {
        User user = repository.findByEmail(email);
        return user;
    }

    @Override
    public User findByEmailAndPassWord(String email, String password) {
        User user = repository.findByEmailAndPassWord(email,password);
        return user;
    }

    @Override
    public User findByUserIdAndPassword(String userId, String pwd) {
        User user = repository.findByUserIdAndPassWord(userId, pwd);
        return user;
    }

    @Override
    public int resetPassword(String pwd, String email) {
        int i = repository.updatePwdByEmail(pwd, email);
        return i;
    }

    @Override
    public String createToken(String email, String name) {
        String token =  JwtUtil.genToken(ImmutableMap.of("email", email, "name", name,
                "ts",Instant.now().getEpochSecond()+""));
        resetToken(token,email);
        return token;
    }

    @Override
    public User auth(String token) {
        Map<String, String> map = null;
        try {
            map = JwtUtil.verifyToken(token);
        } catch (Exception e) {
            throw new UserException(ResultEnum.USER_NOT_LOGIN);
        }
        String email =  map.get("email");
        Long expired = redisTemplate.getExpire(email);
        if (expired > 0L) {
            resetToken(token, email);
            User user = findByEmail(email);
            user.setToken(token);
            return user;
        }
        throw new UserException(ResultEnum.USER_NOT_LOGIN);
    }

    @Override
    public Cookie auth2(String token) {
        Map<String, String> map = null;
        try {
            map = JwtUtil.verifyToken(token);
        } catch (Exception e) {
            throw new UserException(ResultEnum.USER_NOT_LOGIN);
        }
        String email =  map.get("email");
        Long expired = redisTemplate.getExpire(email);
        if (expired > 0L) {
            resetToken(token, email);
            Cookie cookie = new Cookie(TOKEN_COOKIE, token);
            return cookie;
        }
        throw new UserException(ResultEnum.USER_NOT_LOGIN);
    }

    @Override
    public void invalidate(String token) {
        Map<String, String> map = JwtUtil.verifyToken(token);
        redisTemplate.delete(map.get("email"));
    }

    private void resetToken(String token, String email) {
        redisTemplate.opsForValue().set(email, token);
        redisTemplate.expire(email, 30, TimeUnit.MINUTES);
    }

}
